/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */
#include "CameraObject.h"
#include "SceneObject.h"

namespace PQEngine
{
	CameraObject::CameraObject(SceneObject* scene)
		: GameObject(scene,GAME_OBJECT_CAMERA),_camera(0)
	{
		this->setName("Camera Object");
		
		_camera=scene->getSceneManager()->createCamera("Camera"+Ogre::StringConverter::toString(getId()));
		//_camera->setPosition(0,0,0);


		//_camera->setNearClipDistance(1.0f);
		//_camera->setFarClipDistance(2000.0f);

		//_sceneNode->setPosition(0,0,0);
		_sceneNode->attachObject(_camera);
		
		//now we use auto created render window
		Ogre::RenderWindow* window=_sceneObject->getRenderWindow();
		window->removeAllViewports();
		_viewport= window->addViewport(_camera);
		_viewport->setBackgroundColour(scene->getRenderProperty().getBackground());
        _camera->setAspectRatio(Ogre::Real(_viewport->getActualWidth())/Ogre::Real(_viewport->getActualHeight()));

		_sceneNode->setFixedYawAxis(true);
	}


	void CameraObject::resetViewport()
	{
		Ogre::RenderWindow* window=_sceneObject->getRenderWindow();
		window->removeAllViewports();
		_viewport= window->addViewport(_camera);
		_viewport->setBackgroundColour(_sceneObject->getRenderProperty().getBackground());
        _camera->setAspectRatio(Ogre::Real(_viewport->getActualWidth())/Ogre::Real(_viewport->getActualHeight()));

	}

	Ogre::Vector3 CameraObject::getPositionOfFrameObject(GameObject* obj,Ogre::Real k)
	{
		if(obj==NULL||obj->isTerrain()){
			return Ogre::Vector3();
		}
		
		Ogre::AxisAlignedBox bbox=obj->getBoundingBox();
		if(bbox==Ogre::AxisAlignedBox::BOX_NULL){
			return Ogre::Vector3();
		}

		Ogre::Vector3 size=bbox.getHalfSize();
		Ogre::Vector3 center=bbox.getCenter();
		size+=Ogre::Vector3(size.z,size.z,size.z);

		float distance=std::max(std::max(size.x,size.y),size.z) * k;
		Ogre::Vector3 lookat=getDirection()*distance;

		Ogre::Vector3 position=center-lookat;
		return position;
	}

	void CameraObject::setDirection(Ogre::Vector3 dir)
	{
		if(_sceneNode){
			_sceneNode->resetOrientation();
			
			_sceneNode->setDirection(dir,Ogre::Node::TS_WORLD);
		}
	}


	Ogre::Vector3 CameraObject::getDirection()
	{
		return _sceneNode->_getDerivedOrientation()* -Ogre::Vector3::UNIT_Z;
	}

	Ogre::Vector3 CameraObject::getUp()
	{
		return _sceneNode->_getDerivedOrientation()* Ogre::Vector3::UNIT_Y;
	}

	Ogre::Vector3 CameraObject::getRight()
	{
		return _sceneNode->_getDerivedOrientation()* Ogre::Vector3::UNIT_X;
	}


	void CameraObject::yaw(Ogre::Degree deg)
	{
		_sceneNode->yaw(deg);

	}

	void CameraObject::pitch(Ogre::Degree deg)
	{
		_sceneNode->pitch(deg);
	}

	void CameraObject::moveRelative(const Ogre::Vector3& vec)
	{
		Ogre::Vector3 trans = _sceneNode->getOrientation() * vec;
		Ogre::Vector3 pos=_sceneNode->getPosition()+trans;
		_sceneNode->setPosition(pos);
	}

	Ogre::SceneNode* CameraObject::getCameraNode()
	{
		return _sceneNode;

	}

}
